/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package ace.game;

import java.io.IOException;
import java.util.Hashtable;
import java.util.Vector;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import ace.system.Utilities;
import ace.system.xml.XmlNode;
import ace.system.xml.XmlReaderWriter;

/**
 *
 * @author LegACy
 */
public class Sprite {
	protected Sprite() {
		//Initialize
		mX			= 0;
		mY			= 0;
		mFrame		= 0;
		mDelay		= 0;
		mTimer		= 0;
		mWidth		= 0;
		mHeight		= 0;
		mImages		= null;
		mAnimating	= true;
		mLooping	= true;
        mBouncing   = false;
        mIncrease   = 1;
		mAnimationRow = 0;
	}

	public Sprite clone() {
		Sprite sprite = new Sprite();

		sprite.mX			= mX;
		sprite.mY			= mY;
		sprite.mFrame		= mFrame;
		sprite.mDelay		= mDelay;
		sprite.mTimer		= mTimer;
		sprite.mWidth		= mWidth;
		sprite.mHeight		= mHeight;
		sprite.mAnimating	= mAnimating;
		sprite.mLooping		= mLooping;
		sprite.mImages		= mImages;
		return sprite;
	}

	public Sprite(String image, int row, int column) throws IOException {
		this(image, 0, 0, row, column);
	}

	public Sprite(String image, int xPos, int yPos, int row, int column) throws IOException {
		this(Image.createImage(image), xPos, yPos, row, column);
	}

	public Sprite(Image image, int xPos, int yPos, int row, int column) {
		//Default
		this();

		makeSprite(image, xPos, yPos, row, column, 0);
	}

	public Sprite(XmlNode xml, String baseDirectory) {
		this();

		String imagePath = null;
		int row		= 0;
		int col		= 0;

		for(int i=0; i < xml.getChildren().size(); ++i) {
			//Get tag name and it's value
			String Tag		= ((XmlNode)xml.getChildren().elementAt(i)).getNodeName();
			String Value	= ((XmlNode)((XmlNode) xml.getChildren().elementAt(i)).getChildren().elementAt(0)).getNodeValue();

			//Save data
			if(Tag.equals("name"))				imagePath	= Value + ".png";
			else if (Tag.equals("row"))			row			= Integer.parseInt(Value);
			else if (Tag.equals("column"))		col			= Integer.parseInt(Value);
			else if (Tag.equals("animation"))	mDelay		= Integer.parseInt(Value);
			else if (Tag.equals("bounce"))      mBouncing	= Integer.parseInt(Value) == 1;
			else if (Tag.equals("bouncing"))    mBouncing	= Integer.parseInt(Value) == 1;
			else if (Tag.equals("looping"))     mLooping	= Integer.parseInt(Value) == 1;
		}

		try {
			if (baseDirectory != null) {
				imagePath = baseDirectory + "/" + imagePath;
			}
			final Image image = Image.createImage(imagePath);
			makeSprite(image, 0, 0, row, col, mDelay);
		} catch (IOException iEx) {}
	}

	private void makeSprite(Image image, int xPos, int yPos, int row, int column, long delay) {
		//Set position
		mX = xPos;
		mY = yPos;

		//Set width and row
		mWidth	= image.getWidth() / column;
		mHeight	= image.getHeight() / row;

		mImages = new Image[row][column];

		//Splice image
		for (int x = 0; x < column; x++) {
			for (int y = 0; y < row; y++) {
				// for each tintm
				mImages[y][x] = Image.createImage(image, x * mWidth, y * mHeight, mWidth, mHeight, 0);
			}
        }

		//Set delay
		mDelay = delay;
		if (mDelay > 0) mAnimating = true;
	}

	public int getWidth() {
		return mWidth;
	}

	public int getHeight() {
		return mHeight;
	}

	public void setAnimating(boolean animating) {
		//Set animation
		mAnimating = true;
	}

	public void playAnimation(int row, boolean isLooping) {
		mAnimating	= true;
		mLooping	= isLooping;
		mAnimationRow = row;
	}

	public void setFrame(int frame) {
		//Set frame
		mFrame = frame;

		//Correct frame
		if (mFrame < 0)                     mFrame = 0;
		if (mFrame >= mImages[0].length)	mFrame = mImages[0].length - 1;
	}

	public void setPosition(int x, int y) {
		mX = x;
		mY = y;
	}

	public void setTilePosition(int x, int y, int offsetX, int offsetY) {
		//Set position
		mX = (x * Utilities.TILE_WIDTH)  + offsetX;
		mY = (y * Utilities.TILE_HEIGHT) + offsetY;
	}

	public void update(long time) {
		//If animating
		if (mAnimating) {
			//Increase timer
			mTimer += time;

			//If more than delay
			if (mTimer >= mDelay) {
				//Reset
				mTimer -= mDelay;

				//Next frame
				mFrame += mIncrease;
				if (mFrame >= mImages[0].length || mFrame < 0) {
					if (!mLooping && (!mBouncing || mIncrease == -1)) {
						mAnimating = false;
                        // reverse frame back by 1 (since it's corner frame)
                        mFrame -= mIncrease;
					} else {
                        if (mBouncing) {
                            mIncrease = -mIncrease;
                            mFrame += mIncrease;
                        } else {
                            mFrame = 0;
                        }
                    }
				}
			}
		}
	}

	public void draw(Graphics g) {
		draw(g, Graphics.LEFT | Graphics.TOP);
	}

	public void draw(Graphics g, int flag) {
		//Draw
		g.drawImage(mImages[mAnimationRow][mFrame], mX, mY, flag);
	}
	
	//Tint colors
	protected static Hashtable sTints;

	//Data
	protected int		mX;
	protected int		mY;
	protected int		mWidth;
	protected int		mHeight;
	protected Image[][]	mImages;

	//Animation
	protected int		mFrame;
	protected int		mAnimationRow;
	protected long		mDelay;
	protected long		mTimer;
	protected boolean	mAnimating;
	protected boolean	mLooping;
    protected boolean   mBouncing;
    // for bouncing things
    private int         mIncrease;
}
